//
//  note.h
//  LZNeiHan
//
//  Created by 梁梓烽 on 16/9/28.
//  Copyright © 2016年 liangzifeng. All rights reserved.
//

1.
导航条:
默认是有一点透明的
uinavigationBar->_navigationBarBackground (uiimageview , _uibackdropview(_uibackdropeffectview uiview))


当设置了 [navigationBar setTranslucent:NO] 后,导航条变得不透明,白色
uinavigationBar->_navigationBarBackground (uiimageview) uiimageview是一条线

如何隐藏这条线条呢?

[navigationBar setShadowImage:[UIImage new]];
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
uinavigationBar->_navigationBarBackground

设置导航条的主题颜色

setBarTintColor


uitabbar uitabbaritem   uinavigationBar  uibarbuttonitem 可以通过appearance来获取全局对象,来做统一设置 , 注意主题颜色很好用

遵守了appearance协议的类,才可以调用 appearance来获得全局外观对象


2.
[UIView setAnimationsEnabled:NO];
// 如果禁止了uiview的animation,那么下面的block会执行,但是没有动画效果,马上发生变化
[UIView animateWithDuration:3 animations:^{
    self.button.alpha =0;
}];


3.a requireGestureRecognizerToFail : b方法的使用
  当一个view上面有多个手势的手势的时候,可以用这个方法来做约束,只有b失效a才会识别执行对应的aciton, 同理反之
// 单击的 Recognizer
UITapGestureRecognizer  *singleRecognizer =[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTapFrom)];
singleRecognizer.numberOfTapsRequired = 1; // 单击
[self.redView addGestureRecognizer:singleRecognizer];

// 单击的 Recognizer
UITapGestureRecognizer  *doubleRecognizer =[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTapFrom)];
doubleRecognizer.numberOfTapsRequired = 2; // 双击
[self.redView addGestureRecognizer:doubleRecognizer];

//如果双击确定偵測失败才會触发单击
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];


4.A  bringSubviewToFront B   把A中的subviews中的B 带到最前面


5. uiviewcontroller  edgesForExtendedLayout 属性
   //The extended edges to use for the layout.
包 一个普通的控制器a -->那么默认控制器view放到导航控制器上是占全屏幕的,
这个时候普通控制器a 的edgesForExtendedLayout 属性默认是 UIRectEdgeAll

当把控制器a的edgesForExtendedLayout这个属性 设置为UIRectEdgeNone 后, 控制器a 的view放到
导航控制器上就不是占全屏幕了,而是在导航条下面.
一个导航控制器b

6.c语言知识
char a = 'a'   字符变量   //&a字符变量的地址
char *b ="liangzifeng"  指针来存字符数组, 指针变量指向该数组第一个元素的地址
   // &b表示第一个元素地址
const void *a  表示指向任意类型的指针变量a , *a的值不能变, const修饰右边的量为只读


7.动态给某个类添加属性 runtime
下面的key 可以这样声明
static const char *key  -->如果是这样声明的话, 那么就直接传key
static const char key   --> 如果是这样声明的话, 那么就传 &key进去
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

id objc_getAssociatedObject(id object, const void *key)


8.@synthesize age = _age
生成属性的setter  getter 方法的实现
-(int)age
{
    return _age;
}

-(void)setAge:(int)age
{
    _age=age;
}


一个类,如果声明了一个属性,然后重写它的set get 方法 ,那么下划线的成员变量是不会生成的 .
在 implemtation中 加上 .@synthesize age = _age 那么下划线的成员变量就可以访问了



9. layer
self.layer.masksToBounds = YES;
// 栅格化 - 提高性能
// 设置栅格化后，图层会被渲染成图片，并且缓存，再次使用时，不会重新渲染
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
self.layer.shouldRasterize = YES;



10.rotate.cumulative = YES;  动画的值是通过累积来变化的


11. 子控件aview和父控件bview一样大
[bview addSubview: aview];
aview.frame  =bview.bounds;


12.遵守协议,其实就是将协议中的方法声明拿过来,如果是在.h中声明的话,那么方法就拿到.h中,如果是在.m中声明的话,那么方法的声明就放到.m中


13. 有待探究???
tableview 和tableviewcell的  separatorInset属性
uiview的 layoutMargins 属性


14.NSLog(@"%@", [[Person class]description]);
输出结果:   Person  类名


15.tableview beginUpdates endUpdates 动画块用法  有待探究???

我们在做UITableView的修改，删除，选择时，需要对UITableView进行一系列的动作操作。
这样，我们就会用到
[tableView beginUpdates];
if (newCount<=0) {
    [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]withRowAnimation:UITableViewRowAnimationLeft];
}

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationLeft];
[tableView endUpdates];

向上面一段代码，就是动态删除UITableView 的UITableViewCell的操作。
因为，如果我们的UITableView是分组的时候，我们如果删除某个分组的最后一条记录时，相应的分组也将被删除。所以，必须保证UITableView的分组，和cell同时被删除。
所以，就需要使用beginUpdates方法和endUpdates方法，将要做的删除操作“包”起来！

beginUpdates方法和endUpdates方法是什么呢？


这两个方法，是配合起来使用的，标记了一个tableView的动画块。
分别代表动画的开始开始和结束。
两者成对出现，可以嵌套使用。
一般，在添加，删除，选择 tableView中使用，并实现动画效果。
在动画块内，不建议使用reloadData方法，如果使用，会影响动画。


一般什么时候使用这么一个动画块呢？

一般在UITableView执行：删除行，插入行，删除分组，插入分组时，使用！用来协调UITableView的动画效果。

插入指定的行，
在执行该方法时，会对数据源进行访问（分组数据和行数据），并更新可见行。所以，在调用该方法前，应该先更新数据源
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

插入分组到制定位置
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
插入一个特定的分组。如果，指定的位置上已经存在了分组，那么原来的分组向后移动一个位置。

删除制定位置的分组
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
删除一个制定位置的分组，其后面的分组向前移动一个位置。

移动分组
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection
移动原来的分组从一个位置移动到一个新的位置。如果，新位置上若存在某个分组，那这某个分组将会向上（下）移动到临近一个位置。该方法，没有动画参数。会直接移动。并且一次只能移动一个分组。

在如上方法中，建议使用该动画块进行操作！

希望对你有所帮助！


16. AFURLResponseSerialization 的设计思想,这个协议,用来统一方法接口,然后http,json,xml,image等解析器遵守这个协议,
    面向协议编程


17.枚举类型定义
typedef NS_ENUM(NSInteger, NHBaseTableViewRowAnimation)
{
    Fade = UITableViewRowAnimationFade,
    Right = UITableViewRowAnimationRight,
    Left = UITableViewRowAnimationLeft,
    Top = UITableViewRowAnimationTop,
    Bottom = UITableViewRowAnimationBottom,
    None = UITableViewRowAnimationNone,
    Automatic = 100
};

typedef NS_ENUM(NSUInteger,NHBaseTableVcRefreshType)
{
    /** 无法刷新*/
    NHBaseTableVcRefreshTypeNone = 0,
    /** 只能下拉刷新*/
    NHBaseTableVcRefreshTypeOnlyCanRefresh ,
    /** 只能上拉加载*/
    NHBaseTableVcRefreshTypeOnlyCanLoadMore,
    /** 能刷新*/
    NHBaseTableVcRefreshTypeRefreshAndLoadMore
    
};


18.
afn源码
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
    failure(nil, serializationError);
});
#pragma clang diagnostic pop
}
啥玩意?



19 设计一个类的时候:
考虑它是什么,父类是什么
考虑它的作用是什么,需要什么参数
>有什么状态量(就是每个对象都有可能不同的量,就设置为属性),属性考虑要暴露给外界还是不暴露给外界.考虑如果外界设置的话,容错处理重写set方法
>方法接口,一般会先设计成类方法,但在写的过程中可能会发现类方法中调用了成员变量,那么再改成对象方法.
外面想通过它拿到什么值 ,通过什么方式和外界进行传值(block 代理 属性 都可以传值), block和代理并存的时候考虑block优先级先行
考虑它的创建方式(单例?类工厂方法,自定义构造方法)


像这个类,我就想直接调NHBaseRequest的一个接口, 然后就拿到 success response message这3个值
底层是调用 afn  afhttpsessionmanager 的get  set 接口,对比afn需要的参数和你想通过这个接口拿到的值之间的差别,
再去写代码去验证


20. 控件的四部曲   //创建 持有 设置属性 添加 给frame

21.
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:nil]) {
    [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:NO attributes:nil error:nil];
}
fileExistsAtPath:isDirectory  //判断你给定的path,是不是文件夹/file/ isDirectory判断是否是文件夹
createDirectoryAtPath:withIntermediateDirectories:attributes:error //根据你给定的path,创建文件目录.
